#include<iostream>
#include<unistd.h>
#include<cstring>
#include<pthread.h>
using std::endl;
using std::cout;
int tickets=10000;
typedef struct MutexInfo{
    char _name[64];
    pthread_mutex_t* _mutex;
}MutexInfo;
void* Buyticket(void* argc)
{
    MutexInfo* mutex=(MutexInfo*)argc;
    while(true)
    {
        pthread_mutex_lock(mutex->_mutex);
        if(tickets>0)
        {
            printf("%s:%lu Get ticket:%d!\n",mutex->_name,pthread_self(),tickets--);
            pthread_mutex_unlock(mutex->_mutex);
            usleep(10);
        }
        else{
            printf("%s::%lu There is no ticket!\n",mutex->_name,pthread_self());
            pthread_mutex_unlock(mutex->_mutex);
            break;
        }
    }
    return nullptr;
}
int main()
{
    static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;;
    pthread_t tid1,tid2,tid3,tid4;

    MutexInfo* m1=new MutexInfo();
    MutexInfo* m2=new MutexInfo();
    MutexInfo* m3=new MutexInfo();
    MutexInfo* m4=new MutexInfo();
    m1->_mutex=&mutex;
    m2->_mutex=&mutex;
    m3->_mutex=&mutex;
    m4->_mutex=&mutex;
    strcpy(m1->_name,"thread 1");
    strcpy(m2->_name,"thread 2");
    strcpy(m3->_name,"thread 3");
    strcpy(m4->_name,"thread 4");
    pthread_create(&tid1,nullptr,Buyticket,(void*)m1);
    pthread_create(&tid2,nullptr,Buyticket,(void*)m2);
    pthread_create(&tid3,nullptr,Buyticket,(void*)m3);
    pthread_create(&tid4,nullptr,Buyticket,(void*)m4);
    
    pthread_join(tid1,nullptr);
    cout<<"Main thread has joined thread 1!"<<endl;
    pthread_join(tid2,nullptr);
    cout<<"Main thread has joined thread 2!"<<endl;
    pthread_join(tid3,nullptr);
    cout<<"Main thread has joined thread 3!"<<endl;
    pthread_join(tid4,nullptr);
    cout<<"Main thread has joined thread 4!"<<endl;
    return 0;
}
